﻿

//参考stack overflow的代码（使用libharu显示中文字符）
//bool textConvertToPDF(std::vector<std::string> text, std::string filePath)
//
//{
//
//    HPDF_Doc pdf = HPDF_New(nullptr, nullptr);
//
//    if (!pdf) {
//
//        //throw std::runtime_error("Failed to create PDF document");
//
//        return true;
//
//    }
//
//    std::vector<std::string> lines = text;
//
//    //lines.push_back(text);
//
//    try {
//
//        // 添加一个页面
//
//        HPDF_Page page = HPDF_AddPage(pdf);
//
//        HPDF_UseCNSFonts(pdf);
//
//        HPDF_UseCNSEncodings(pdf);
//
//        HPDF_SetCompressionMode(pdf, HPDF_COMP_ALL);
//
//        // 设置页面尺寸（A4）
//
//        HPDF_Page_SetSize(page, HPDF_PAGE_SIZE_A4, HPDF_PAGE_PORTRAIT);
//
//       // HPDF_SetCurrentEncoder(pdf, "UTF-8"); //这一行有问题
//
//        HPDF_Font font = HPDF_GetFont(pdf, HPDF_LoadTTFontFromFile(pdf, "C:/Windows/Fonts/simkai.ttf", HPDF_TRUE), "GB-EUC-H");//这里也不能写utf-8,不然显示不出来
//
//
//
//
//        HPDF_Page_SetFontAndSize(page, font, 12);
//
//        // 设置起始位置
//
//        float x = 50; // 左边距
//
//        float y = HPDF_Page_GetHeight(page) - 50; // 顶部边距
//
//        float line_height = 14; // 每行文本的高度（包含行间距）
//
//        // 绘制每一行文本
//
//        HPDF_Page_BeginText(page);
//
//        for (const auto& line : lines) {
//
//            HPDF_Page_TextOut(page, x, y, line.c_str());
//
//            y -= line_height; // 移动到下一行
//
//            if (y < 50) { // 如果超出页面底部，创建新页面
//
//                HPDF_Page_EndText(page);
//
//                page = HPDF_AddPage(pdf);
//
//                HPDF_Page_SetSize(page, HPDF_PAGE_SIZE_A4, HPDF_PAGE_PORTRAIT);
//
//                HPDF_Page_SetFontAndSize(page, font, 12);
//
//                y = HPDF_Page_GetHeight(page) - 50;
//
//                HPDF_Page_BeginText(page); 
//
//            }
//
//        }
//
//        HPDF_Page_EndText(page);
//
//        // 保存 PDF 文件
//
//        HPDF_SaveToFile(pdf, filePath.c_str());
//
//    }
//    catch (...) {
//
//        HPDF_Free(pdf);
//
//        //throw;
//
//        return false;
//
//    }
//
//    HPDF_Free(pdf);
//
//    return true;
//
//}
//
//
//
//int main() {
//    // 示例文本（包含中文）
//    std::vector<std::string> text = {
//        "灞爨夔肇羹回盥龆曦寰囡鼻接祁树氚圜灌囔屦训幕犹电杰师永印品一丁七万三上下",
//        "不与专且世丙业东丝丢两严个中丰临为主举么义之乐乘九也习书买乱了争事二于云",
//        "互五些亡交产享京亮亲人什仅今介仍从仔他付代令以仪们仰件价任份企休众优伙会"
//    };
//
//    // 保存文件的路径
//    std::string filePath = "output_chinese.pdf";
//
//    // 调用 textConvertToPDF 函数生成 PDF
//    if (textConvertToPDF(text, filePath)) {
//        std::cout << "PDF created successfully!" << std::endl;
//    }
//    else {
//        std::cerr << "Failed to create PDF." << std::endl;
//    }
//
//    return 0;
//}


/*日志  已经搞定了指定文本输出到pdf的形式  根据上述代码进行修改将所有字符全放进去*/

//#include <iostream>
//#include <fstream>
//#include <iomanip>
//
//void generateGB2312Characters(const std::string& filename) {
//    // 打开文件以写入字符
//    std::ofstream outFile(filename, std::ios::out | std::ios::binary);
//    if (!outFile.is_open()) {
//        std::cerr << "无法打开文件 " << filename << " 进行写入！" << std::endl;
//        return;
//    }
//
//    // 遍历 GB2312 编码范围：高字节（区字节）和低字节（位字节）
//    for (unsigned char high = 0xA1; high <= 0xF7; ++high) {
//        for (unsigned char low = 0xA1; low <= 0xFE; ++low) {
//            unsigned short code = (high << 8) | low;
//
//            // 跳过保留的空位 D7FA-D7FE
//            if (code >= 0xD7FA && code <= 0xD7FE) {
//                continue;
//            }
//
//            // 将高字节和低字节写入文件
//            outFile.put(high);
//            outFile.put(low);
//        }
//    }
//
//    outFile.close();
//    std::cout << "GB2312 字符集（EUC-CN 格式）已成功写入 " << filename << " 文件。" << std::endl;
//}
//
//int main() {
//    // 调用函数生成 GB2312 字符并保存到文件
//    generateGB2312Characters("gb2312_characters_euc_cn.txt");
//    return 0;
//}


/*日志 获取GB2312编码表的所有文字*/



#include <iostream>
#include <fstream>
#include <vector>
#include <hpdf.h>
#include <string>
#include <set>

std::set<unsigned short> gb2312_invalid{
       0xA1A1, 0xA2A1, 0xA2A2, 0xA2A3, 0xA2A4, 0xA2A5, 0xA2A6, 0xA2A7, 0xA2A8, 0xA2A9,
       0xA2AA, 0xA2AB, 0xA2AC, 0xA2AD, 0xA2AE, 0xA2AF, 0xA2B0, 0xA2E3, 0xA2E4, 0xA2EF,
       0xA2F0, 0xA2FD, 0xA2FE, 0xA4F4, 0xA4F5, 0xA4F6, 0xA4F7, 0xA4F8, 0xA4F9, 0xA4FA,
       0xA4FB, 0xA4FC, 0xA4FD, 0xA4FE, 0xA5F7, 0xA5F8, 0xA5F9, 0xA5FA, 0xA5FB, 0xA5FC,
       0xA5FD, 0xA5FE, 0xA6B9, 0xA6BA, 0xA6BB, 0xA6BC, 0xA6BD, 0xA6BE, 0xA6BF, 0xA6C0,
       0xA6F6, 0xA6F7, 0xA6F8, 0xA6F9, 0xA6FA, 0xA6FB, 0xA6FC, 0xA6FD, 0xA6FE, 0xA7C2,
       0xA7C3, 0xA7C4, 0xA7C5, 0xA7C6, 0xA7C7, 0xA7C8, 0xA7C9, 0xA7CA, 0xA7CB, 0xA7CC,
       0xA7CD, 0xA7CE, 0xA7CF, 0xA7D0, 0xA7F2, 0xA7F3, 0xA7F4, 0xA7F5, 0xA7F6, 0xA7F7,
       0xA7F8, 0xA7F9, 0xA7FA, 0xA7FB, 0xA7FC, 0xA7FD, 0xA7FE, 0xA8BC, 0xA8C1, 0xA8C2, 
       0xA8C3, 0xA8C4, 0xA8EA, 0xA8EB, 0xA8EC, 0xA8ED, 0xA8EE, 0xA8EF, 0xA8F0, 0xA8F1, 
       0xA8F2, 0xA8F3, 0xA8F4, 0xA8F5, 0xA8F6, 0xA8F7, 0xA8F8, 0xA8F9, 0xA8FA, 0xA8FB, 
       0xA8FC, 0xA8FD, 0xA8FE, 0xA9A1, 0xA9A2, 0xA9A3, 0xA9F0, 0xA9F1, 0xA9F2, 0xA9F3, 
       0xA9F4, 0xA9F5, 0xA9F6, 0xA9F7, 0xA9F8, 0xA9F9, 0xA9FA, 0xA9FB, 0xA9FC, 0xA9FD, 
       0xA9FE, 0xA8BF
       
};



 //生成 GB2312 编码支持的所有字符（EUC-CN 格式）
void generateGB2312Characters(std::vector<std::string>& chars) {
    //符号范围
    for (unsigned char high = 0xA1; high <= 0xA9; ++high) {
        for (unsigned char low = 0xA1; low <= 0xFE; ++low) {
            unsigned short code = (high << 8) | low;

            if (gb2312_invalid.find(code) != gb2312_invalid.end()) {
                continue;
            }
            std::string ch(1, high);
            ch.push_back(low);
            chars.push_back(ch);
        }
    }
    
    //汉字范围
    for (unsigned char high = 0xB0; high <= 0xF7; ++high) {
        for (unsigned char low = 0xA1; low <= 0xFE; ++low) {
            unsigned short code = (high << 8) | low;

            // 跳过保留的空位 D7FA-D7FE
            if (code >= 0xD7FA && code <= 0xD7FE) {
                continue;
            }

            
            std::string ch(1, high);
            ch.push_back(low);
            chars.push_back(ch);
        }
    }
}

 //将所有 GB2312 字符输出到 PDF
bool generateGB2312TextToPDF(const std::string& filePath) {
    // 生成所有 GB2312 字符
    std::vector<std::string> chars;
    generateGB2312Characters(chars);

    // 创建 PDF 文档
    HPDF_Doc pdf = HPDF_New(nullptr, nullptr);
    if (!pdf) {
        std::cerr << "无法创建 PDF 文档！" << std::endl;
        return false;
    }

    // 设置 PDF 页面
    HPDF_Page page = HPDF_AddPage(pdf);
    HPDF_UseCNSFonts(pdf);
    HPDF_UseCNSEncodings(pdf);
    HPDF_SetCompressionMode(pdf, HPDF_COMP_ALL);
    HPDF_Page_SetSize(page, HPDF_PAGE_SIZE_A4, HPDF_PAGE_PORTRAIT);

    // 加载楷体字体
    // HPDF_Font font = HPDF_GetFont(pdf, HPDF_LoadTTFontFromFile(pdf, "C:/Windows/Fonts/simkai.ttf", HPDF_TRUE), "GB-EUC-H");
    //加载Arial unicode MS字体，非嵌入的方式
    HPDF_Font font = HPDF_GetFont(pdf, HPDF_LoadTTFontFromFile(pdf, "C:/Windows/Fonts/ARIALUNI.TTF", HPDF_FALSE), "GB-EUC-H");
 


    // 设置字体和字号
    HPDF_Page_SetFontAndSize(page, font, 12);

    // 页面设置
    float x = 50; 
    float y = HPDF_Page_GetHeight(page) - 50; 
    float page_height = HPDF_Page_GetHeight(page); 
    float page_width = HPDF_Page_GetWidth(page); 

    // 每行字符数和每页行数
    int characters_per_line = 15;
    int lines_per_page = 20; 
    int char_count = 0; // 当前输出的字符数

    // 计算字符之间的空格宽度
    float total_line_width = characters_per_line * 12; // 每行15个字符，每个字符宽度12点
    float space_between_characters = (page_width - 100 - total_line_width) / (characters_per_line - 1); // 计算字符之间的空格

    // 计算行高
    float line_height = (page_height - 100) / lines_per_page; // 计算每行的高度，确保20行填满页面

    HPDF_Page_BeginText(page);

    // 输出所有字符
    for (size_t i = 0; i < chars.size()-1; ++i) { //char.size()-1,减一的目的是为了不打印最后一个字符
        
        HPDF_Page_TextOut(page, x, y, chars[i].c_str());

        // 调整 x 坐标，用空格填充
        x += 12 + space_between_characters; // 每个字符宽度加上空格的宽度

        char_count++;
        if (char_count % characters_per_line == 0) {
            // 换行
            y -= line_height;
            x = 50; // 重置 x 位置
        }

        if (char_count % (characters_per_line * lines_per_page) == 0) {
            // 如果当前页已满，添加新的一页
            HPDF_Page_EndText(page);
            page = HPDF_AddPage(pdf);
            HPDF_Page_SetSize(page, HPDF_PAGE_SIZE_A4, HPDF_PAGE_PORTRAIT);
            HPDF_Page_SetFontAndSize(page, font, 12);
            y = page_height - 50;
            x = 50;
            HPDF_Page_BeginText(page);
        }
    }

    HPDF_Page_EndText(page);

    // 保存 PDF 文件
    HPDF_SaveToFile(pdf, filePath.c_str());
    HPDF_Free(pdf);

    std::cout << "所有 GB2312 字符已成功写入 PDF 文件 " << filePath << std::endl;
    return true;
}

int main() {
   
    generateGB2312TextToPDF("kaiti_gb2312_new.pdf");
    return 0;
}
